package com.llh.demo4tree.util

import com.llh.demo4tree.entity.MoveDirection
import com.llh.demo4tree.entity.TreeVO
import com.llh.demo4tree.model.TreeNode
import org.apache.logging.log4j.kotlin.Logging

internal const val split = ","
internal const val max_order = 999
internal const val min_order = -999

object NodePathUtil : Logging {

    fun contact(path: String?, pId: Int): String {
        return if (null == path) "$pId"
        else "$path$split$pId"
    }

    fun splitPathToInt(path: String?): List<Int> {
        if (null == path) return emptyList()
        return path.split(split)
            .map { it.toInt() }
            .toList()
    }

    fun convertTreeVO(node: TreeNode): TreeVO {
        return TreeVO(
            id = node.id,
            name = node.name,
            nodePath = node.nodePath,
            pId = node.pId,
            orderNum = node.orderNum
        )
    }

    fun assembleTreeData(dataList: List<TreeNode>, node: TreeNode): TreeVO {
        return assembleTreeData(dataList, convertTreeVO(node))
    }

    /**
     * 组装树形结构数据的方法
     */
    fun assembleTreeData(
        dataList: List<TreeNode>,
        root: TreeVO = TreeVO(null, "root", open = true, orderNum = 0)
    ): TreeVO {
        val map = mutableMapOf<Int?, TreeVO>()
        map[root.id] = root
        // 先缓存所有结点，避免因顺序问题造成某些结点未插入到根结点中
        dataList.forEach {
            val node = TreeVO(
                id = it.id,
                name = it.name,
                pId = it.pId,
                nodePath = it.nodePath,
                orderNum = it.orderNum,
            )
            map[it.id] = node
        }

        dataList.forEach {
            if (map.containsKey(it.pId)) {
                val node = map[it.id]
                if (null != node) {
                    map[it.pId]?.childList?.add(node)
                }
            }
        }

        return map[root.id]!!
    }

    /**
     * 当前目标节点为空时，则表明需要移动根节点之下。
     * 默认为会放到最后一个
     */
    fun computeOrderNum(
        dataList: List<TreeNode>
    ): Int {
        val old = dataList.filter {
            it.pId == null
        }.maxOfOrNull { it.orderNum } ?: 0
        return old + 1
    }

    /**
     * 计算移动之后的排序号
     */
    fun computeOrderNum(
        targetNode: TreeNode,
        direction: MoveDirection,
        dataList: List<TreeNode>
    ): Int {

        var orderNum = 0
        if (direction == MoveDirection.prev) {
            orderNum = targetNode.orderNum - 1
        }
        if (direction == MoveDirection.next) {
            orderNum = targetNode.orderNum + 1
        }
        // 移动节点内部时需要找出它子节点最大序号，再+1
        if (direction == MoveDirection.inner) {
            val old = dataList.filter {
                it.pId == targetNode.id
            }.maxOfOrNull { it.orderNum } ?: 0
            orderNum = old + 1
        }

        // 设定排序号取值范围，避免数据溢出
        return when {
            orderNum > max_order -> max_order
            orderNum < min_order -> min_order
            else -> orderNum
        }
    }


    /**
     * 根据设定的pid遍历出此结点的路径
     */
    fun nodePathTraverse(
        node: TreeNode,
        dataList: List<TreeNode>
    ): String? {
        var iteration = node
        val path = arrayListOf<Int>()
        while (iteration.pId != null) {
            val parent = dataList.firstOrNull { it.id == iteration.pId }

            if (null == parent) {
                logger.debug("未找到id: ${iteration.pId} 为的节点信息")
                return null
            }
            path.add(parent.id)
            iteration = parent
        }
        path.reverse()
        return path.joinToString(",")


    }


}